package com.zareal.ymcc.service.impl;

import com.zareal.ymcc.doc.CourseSearchDoc;
import com.zareal.ymcc.dto.CourseSearchDto;
import com.zareal.ymcc.repository.CourseRepository;
import com.zareal.ymcc.result.PageList;
import com.zareal.ymcc.service.ICourseSearchService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class CourseSearchServiceImpl implements ICourseSearchService {
    @Autowired
    private CourseRepository courseRepository;
    @Override
    public PageList<CourseSearchDto> search(CourseSearchDto courseSearchDto) {
        String sortField = courseSearchDto.getSortField();
        String sortType = courseSearchDto.getSortType();
        // 1.创建查询条件构造器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        // 2.设置条件
        nativeSearchQueryBuilder.withPageable(PageRequest.of(courseSearchDto.getPage()-1,courseSearchDto.getRows()));
        // 3.判断用户是否给了排序关键词和排序方式，然后再设置排序
        if(!StringUtils.isEmpty(sortField)&&!StringUtils.isEmpty(sortType)){
            // 根据前端传过来的字段然后设置排序条件
            SortOrder sortOrder = sortType.equalsIgnoreCase("ASC") ? SortOrder.ASC : SortOrder.DESC;
            // 判断前端查询的字段是否为空
            if (sortField != null){
                nativeSearchQueryBuilder.withSort(new FieldSortBuilder(sortField).order(sortOrder));
            }
        }
        // 4.设置查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 4.1设置DSL查询条件 Keyword
        if(!StringUtils.isEmpty(courseSearchDto.getKeyword())){
            boolQuery.filter(QueryBuilders.matchQuery("name",courseSearchDto.getKeyword()));
        }
        // 4.2.设置DSL过滤查询 courseTypeId、gradeName、chargeName、priceMin、priceMax
        if (!StringUtils.isEmpty(courseSearchDto.getCourseTypeId())){
            boolQuery.filter(QueryBuilders.termQuery("courseTypeId", courseSearchDto.getCourseTypeId()));
        }
        if (!StringUtils.isEmpty(courseSearchDto.getGradeName())){
            boolQuery.filter(QueryBuilders.termQuery("gradeName", courseSearchDto.getGradeName()));
        }
        if (!StringUtils.isEmpty(courseSearchDto.getChargeName())){
            boolQuery.filter(QueryBuilders.termQuery("charge", courseSearchDto.getChargeName()));
        }
        if (!StringUtils.isEmpty(courseSearchDto.getPriceMin())){
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(courseSearchDto.getPriceMin()));
        }
        if (!StringUtils.isEmpty(courseSearchDto.getPriceMax())){
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(courseSearchDto.getPriceMax()));
        }
        // 5 把设置好的条件对象放到搜索构造器中
        nativeSearchQueryBuilder.withQuery(boolQuery);
        // 6 通过搜索对象构造器得到搜索对象，
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        // 7 根据查询条件查询ES数据
        Page<CourseSearchDoc> search = courseRepository.search(nativeSearchQuery);
        // 8 返回数据
        return new PageList(search.getTotalElements(), search.getContent());
    }
}
